package com.wei.web.middleware.retry.compensate;

import com.google.common.base.Joiner;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;

import javax.annotation.Resource;

/**
 * @author shihuimiao
 * create time: 上午9:52
 */
@Slf4j
public abstract class AbstractRetriableProcessor<T> implements Processor<T> {

    @Value("${spring.application.name}")
    protected String appName;

    @Resource
    CompensateService compensateService;

    public void run(T data) {
        boolean execute = false;
        try {
            execute = execute(data);
        } catch (Exception e) {
            log.error("command execute throw exception;data={}", data, e);
        } finally {
            if (!execute) {
                failSave(getKey(data), data);
            }
        }
    }

    /**
     * 如果需要可以重写生成key的方法
     *
     * @param command
     * @return
     */
    protected String getKey(T command) {
        return Joiner.on("_").join(
                appName, command.getClass().getSimpleName(),
                command.hashCode());
    }

    private void failSave(String key, T data) {
        try {
            compensateService.saveTask(key, data, this.getClass().getCanonicalName(), timesRequired());
        } catch (Exception e) {
            log.error("structureDO error;key={},data={},class={}", key, data, this.getClass(), e);
        }
    }

    /**
     * 全局补偿次数定义在properties中 也支持自定义补偿次数 如果需要可以不复写这个方法
     *
     * @return
     */
    protected Integer timesRequired() {
        return null;
    }


}
